<?php
namespace app\mp\admin;

use app\system\admin\Admin;
use app\common\service\Material as MaterialService;
use app\common\service\Order as OrderService;
use app\common\service\Sku as SkuService;
use app\common\service\OrderMaterial as OrderMaterialService;
use app\common\service\StockLog as StockLogService;
use app\common\service\StockUse as StockUseService;
use app\common\service\Stock as StockService;
use app\common\service\DistributingFeed as DistributingFeedService;
use app\common\service\OrderSize as OrderSizeService;
use app\common\service\GeneralMaterial as GeneralMaterialService;

/**
 * 配料管理
 * @author King
 *
 */
class Distributing extends Admin
{

	protected $hisiModel = '';//模型名称[通用添加、修改专用]
	protected $hisiValidate = '';
	protected $hisiAddScene = '';//添加数据验证场景名
	protected $hisiEditScene = '';//更新数据验证场景名

    public function initialize() {
    	parent::initialize();
    }

    /**
     * 配料管理
     *
     * @author KING
     * @date 2020年7月9日
     *
     * @return string
     */
    public function index()
    {
    	if ($this->request->isAjax()) {
    		$orderService = new OrderService();
    		$skuService = new SkuService();
    		$orderMaterialService = new OrderMaterialService();
    		$stockLogService = new StockLogService();
    		$stockService = new StockService();
    		$distributingFeedService = new DistributingFeedService();
    		$generalMaterialService = new GeneralMaterialService();

    		$factoryId = $this->request->param('factory_id/d', 0);
    		$clientOrdernum = $this->request->param('client_ordernum/s', '');
    		$caichuangOverDateRange    = $this->request->param('caichuang_over_date_range/s');

    		$where[] = ["status", "<", 5];
    		if ($factoryId > 0) $where[] = ['factory_id', '=', $factoryId];
    		if (!empty($clientOrdernum)) $where[] = ["client_ordernum", '=', $clientOrdernum];
            switch (env('env_site')) {
                case 'riwei':
                    $ext_id = trim($this->request->param('ext_id'));
                    if ($ext_id != '') {
                        $temp = db('order')->field('id')->where([['ext_id', '=', $ext_id]])->find();
                        $where[] = ['order_id', '=', $temp['id']];
                    }
                    break;
            }
    		if ($caichuangOverDateRange != '') {
    			list($startTime, $endTime) = array_map('strtotime', explode('~', $caichuangOverDateRange));
    			$where[] = ['create_time', 'between', [$startTime, $endTime+86399]];
    		}

    		$list = db('distributing')->where($where)->order('create_time asc')->select();

    		foreach ($list as $k => $v) {
    			$orderId = $v['order_id'];
    			$orderInfo = $orderService->getInfoById($orderId);
    			if($orderInfo['chejian_status']==1){//裁床状态（0未完成，1为完成）
    				$upData = [
    					'status' => 5,
    					'update_time' => time(),
    				];
    				db('distributing')->where('id', $v['id'])->update($upData);
    				unset($list[$k]);
    				continue;
    			}
    			$list[$k]['pic'] = $skuService->getPicBySku($orderInfo['sku']);

    			// 获取辅料列表，检测配料状态
    			$omList = $orderMaterialService->getListByOrderId($orderId, "accessories", "material_id,material_dosage");
    			if (!$omList || in_array($orderInfo['status'], [2, 99])) {
    				$upData = [
    					'status' => 5,
    					'update_time' => time(),
    				];
    				db('distributing')->where('id', $v['id'])->update($upData);
    				unset($list[$k]);
    				continue;
    			}

    			if (in_array($v['status'], [1, 2, 3])) {
    				$overItems = 0;
    				foreach ($omList as $sv) {
    					$materialId = $sv['material_id'];

    					$materialDosageTotal = $orderInfo['quantity']*$sv['material_dosage'];	// 总的用量
    					$useNum = $stockLogService->getUseNum($materialId, $orderId);	// 已使用量

    					$leftNum = $materialDosageTotal-$useNum; // 还需要的量

    					// 从通用库存扣除给辅料库（如果有），20210323暂停自动转换 通用库存
    					/* if ($leftNum > 0){
    						$generalMaterialService->changeToStock($materialId, $orderId, $sv['mInfo']['material_sku'], $leftNum);
    						$useNum = $stockLogService->getUseNum($materialId, $orderId);	// 再次获取 已使用量
    					} */

    					if ($useNum >= $materialDosageTotal) {
    						$overItems++;
    						continue;
    					}

    					// 库存量
    					$stockNum = $stockService->getStockLeft($materialId);

    					// 采购在途量
    					$ingNum = $distributingFeedService->getIng($materialId, $orderId);

    					if (($stockNum + $useNum) >= $materialDosageTotal) continue;

    					if (($stockNum + $useNum + $ingNum) >= $materialDosageTotal) {	// 在补料中
    						$upData = [
    							'status' => 3,
    							'update_time' => time(),
    						];
    						$list[$k]['status'] = 3;
    						db('distributing')->where('id', $v['id'])->update($upData);
    						break;
    					}

    					// 有欠料
    					$upData = [
    						'status' => 2,
    						'update_time' => time(),
    					];
    					$list[$k]['status'] = 2;
    					db('distributing')->where('id', $v['id'])->update($upData);
    					break;
    				} // end $alist

    				// 全部到位，状态为开始配料
    				if ($overItems == count($omList)) {
    					$upData = [
    						'status' => 1,
    						'update_time' => time(),
    					];
    					db('distributing')->where('id', $v['id'])->update($upData);
    				}
    			}

    			$list[$k]['shipment_time_text'] = date("n月j日", $orderInfo['shipment_time']);
    			$list[$k]['action_text'] = arrayGet(config('mimo.distributing_status'), $list[$k]['status'], '');
    		} // end $list

    		return $this->Json(1, '获取成功！', array_values($list));
    	}

    	$assign = [
    		'factoryKV' => ['' => '请选择'] + getFactoryKV(true),
    	];
    	return $this->assign($assign)->fetch();
    }

    //获取辅料分发情况
    public function getFuliaoDistributingList(){

        $orderService = new OrderService();
        $skuService = new SkuService();
        $orderMaterialService = new OrderMaterialService();
        $stockLogService = new StockLogService();
        $stockService = new StockService();
        $distributingFeedService = new DistributingFeedService();
        $generalMaterialService = new GeneralMaterialService();

        $factoryId = $this->request->param('factory_id/d', 0);
        $clientOrdernum = $this->request->param('client_ordernum/s', '');
        $caichuangOverDateRange    = $this->request->param('caichuang_over_date_range/s');

        $where[] = ["status", "<", 5];
        if ($factoryId > 0) $where[] = ['factory_id', '=', $factoryId];
        if (!empty($clientOrdernum)) $where[] = ["client_ordernum", '=', $clientOrdernum];
        switch (env('env_site')) {
            case 'riwei':
                $ext_id = trim($this->request->param('ext_id'));
                if ($ext_id != '') {
                    $temp = db('order')->field('id')->where([['ext_id', '=', $ext_id]])->find();
                    $where[] = ['order_id', '=', $temp['id']];
                }
                break;
        }
        if ($caichuangOverDateRange != '') {
            list($startTime, $endTime) = array_map('strtotime', explode('~', $caichuangOverDateRange));
            $where[] = ['create_time', 'between', [$startTime, $endTime+86399]];
        }

        $list = db('distributing')->where($where)->order('create_time asc')->select();

        foreach ($list as $k => $v) {
            $orderId = $v['order_id'];
            $orderInfo = $orderService->getInfoById($orderId);
            if($orderInfo['chejian_status']==1){//车间完成状态（0未完成，1为完成）
                $upData = [
                    'status' => 5,
                    'update_time' => time(),
                ];
                db('distributing')->where('id', $v['id'])->update($upData);
                unset($list[$k]);
                continue;
            }
            $list[$k]['pic'] = $skuService->getPicBySku($orderInfo['sku']);

            // 获取辅料列表，检测配料状态
            $omList = $orderMaterialService->getListByOrderId($orderId, "accessories", "material_id,material_dosage");
            //获取到全部辅料后进行过滤，如果没有数据直接设置已完成
            $omList=$this->_setMaterialHide($omList);
            if (!$omList || in_array($orderInfo['status'], [2, 99])) {
                $upData = [
                    'status' => 5,
                    'update_time' => time(),
                ];
                //将订单已经完成的 或已经删除 的设置为分发已完成
                db('distributing')->where('id', $v['id'])->update($upData);
                unset($list[$k]);
                continue;
            }

            if (in_array($v['status'], [1, 2, 3])) {
                $overItems = 0;
                foreach ($omList as $sv) {
                    $materialId = $sv['material_id'];

                    $materialDosageTotal = $orderInfo['quantity']*$sv['material_dosage'];	// 总的用量
                    $useNum = $stockLogService->getUseNum($materialId, $orderId);	// 已使用量
                    $applyUseNum=db('stock_use')->where('order_id', $orderId)->find();//预设置实际使用量
                    $list[$k]['apply_used_id']=empty($applyUseNum) ? 0 :$applyUseNum['id'];
                    $leftNum = $materialDosageTotal-$useNum; // 还需要的量

                    // 从通用库存扣除给辅料库（如果有），20210323暂停自动转换 通用库存
                    /* if ($leftNum > 0){
                        $generalMaterialService->changeToStock($materialId, $orderId, $sv['mInfo']['material_sku'], $leftNum);
                        $useNum = $stockLogService->getUseNum($materialId, $orderId);	// 再次获取 已使用量
                    } */

                    if ($useNum >= $materialDosageTotal) {
                        $overItems++;
                        continue;
                    }

                    // 库存量
                    $stockNum = $stockService->getStockLeft($materialId);

                    // 采购在途量
                    $ingNum = $distributingFeedService->getIng($materialId, $orderId);

                    if (($stockNum + $useNum) >= $materialDosageTotal) continue;

                    if (($stockNum + $useNum + $ingNum) >= $materialDosageTotal) {	// 在补料中
                        $upData = [
                            'status' => 3,
                            'update_time' => time(),
                        ];
                        $list[$k]['status'] = 3;
                        db('distributing')->where('id', $v['id'])->update($upData);
                        break;
                    }

                    // 有欠料
                    $upData = [
                        'status' => 2,
                        'update_time' => time(),
                    ];
                    $list[$k]['status'] = 2;
                    //db('distributing')->where('id', $v['id'])->update($upData);
                    break;
                } // end $alist

                // 全部到位，状态为开始配料
                if ($overItems == count($omList)) {
                    $upData = [
                        'status' => 1,
                        'update_time' => time(),
                    ];
                    db('distributing')->where('id', $v['id'])->update($upData);
                }
            }

            $list[$k]['shipment_time_text'] = date("n月j日", $orderInfo['shipment_time']);
            $list[$k]['action_text'] = arrayGet(config('mimo.distributing_status'), $list[$k]['status'], '');
        } // end $list
        return $this->Json(1, '获取成功1！', array_values($list));
    }

    /**
     * 配料清单
     *
     * @author KING
     * @date 2020年6月5日
     *
     */
    public function detail() {
    	$id = $this->request->param("id/d", 0);
        $isPrint = $this->request->param("is_print/d", 0);
    	$distributingInfo = db('distributing')->where("id", $id)->findOrEmpty();

    	$orderId = $distributingInfo['order_id'];
        $factoryId = $distributingInfo['factory_id'];
    	$orderService = new OrderService();
    	$stockService = new StockService();
    	$orderSizeService = new OrderSizeService();
    	$orderMaterialService = new OrderMaterialService();
    	$generalMaterialService = new GeneralMaterialService();
    	$stockLogService = new StockLogService();
    	$stockUseService = new StockUseService();
    	$distributingFeedService = new DistributingFeedService();

    	$orderInfo = $orderService->getInfoById($orderId);
    	$omList = $orderMaterialService->getListByOrderId($orderId, 'accessories');
    	$osList = $orderSizeService->getListByOrderId($orderId);
    	$shicaiCount = $orderSizeService->getShicaiCount($orderId);
        $omList=$this->_setMaterialHide($omList);

		if ($this->request->isAjax()) {
			$action = $this->request->param("action/s", '');

			// 保存基础数据
			if ($action == 'saveinfo' || $action == 'over') {
				$distributeUserName = $this->request->param("distribute_user_name/s", '');
				$receiptUserName = $this->request->param("receipt_user_name/s", '');
				$distributeTime = $this->request->param("distribute_time/s", 0);
				$receiptTime = $this->request->param("receipt_time/s", 0);
                $allotNumList = $this->request->param('allot_num/a', []);
                foreach ($allotNumList as $materialId => $allotNum) {
                    // 更新到stock_use表
                    $stockUseInfo = db('stock_use')->where('material_id', $materialId)->where('order_id', $orderId)->findOrEmpty();
                    $stockUseData = [
                        'material_id' => $materialId,
                        'order_id' => $orderId,
                        'client_ordernum' => $orderInfo['client_ordernum'],
                        'allot_num' => $allotNum,
                        'admin_id' => ADMIN_ID,
                        'update_time' => time()
                    ];
                    if ($stockUseInfo) {
                        db('stock_use')->where('id', $stockUseInfo['id'])->update($stockUseData);
                    } else {
                        $stockUseData['create_time'] = time();
                        db('stock_use')->insertGetId($stockUseData);
                    }
                }

				$upData = [
					'distribute_user_name' => $distributeUserName,
					'distribute_time' => $distributeTime ? strtotime($distributeTime . ' 00:00:00'):0,
					'receipt_user_name' => $receiptUserName,
					'receipt_time' => $receiptTime ? strtotime($receiptTime . ' 00:00:00'):0,
					'update_time' => time(),
				];
				$u=db('distributing')->where('id', $id)->update($upData);
				if($action=='saveinfo'){
                    return $this->Json(1);
                }
			}

			// 配料完成
			if ($action == 'over') {
                db()->startTrans();
                $allotNumList = $this->request->param('allot_num/a', []);
                $overStatus = true; // 是否配料完成(各辅料配量占比不低于85%)
                foreach ($allotNumList as $materialId => $allotNum) {
                    $omInfo = $orderMaterialService->getInfoByOrderIdMaterialId($orderId, $materialId);
                    $totalNum = $shicaiCount*$omInfo['material_dosage'];
                    $stockNum = $stockService->getStockLeft($materialId,$orderInfo['factory_id']); // 辅料库存
                    $useNum = $stockLogService->getUseNum($materialId, $orderId);//已使用量
                    if ($orderInfo['factory_id']==0) {
                        throw new \Exception("未分厂的订单暂时不能配料"); //需要计算各工厂消耗
                    }

                    if ($allotNum == $useNum) {	// 无需操作库存

                    } elseif ($allotNum > $useNum) {	// 需从库存扣
                        // 继续从辅料库存减扣
                        if (($allotNum - $useNum) > 0) {
                            $ret=$distributingFeedService->useStockNum($materialId, $orderId, $allotNum - $useNum);
                        }
                    } elseif ($allotNum < $useNum) {	// 需退回到库存
                        $distributingFeedService->returnStockNum($materialId, $orderId, $useNum - $allotNum);
                    }

                    // 更新到stock_use表
                    $stockUseInfo = db('stock_use')->where('material_id', $materialId)->where('order_id', $orderId)->findOrEmpty();
                    $stockUseData = [
                        'material_id' => $materialId,
                        'order_id' => $orderId,
                        'client_ordernum' => $orderInfo['client_ordernum'],
                        'allot_num' => $allotNum,
                        'admin_id' => ADMIN_ID,
                        'update_time' => time()
                    ];
                    if ($stockUseInfo) {
                        db('stock_use')->where('id', $stockUseInfo['id'])->update($stockUseData);
                    } else {
                        $stockUseData['create_time'] = time();
                        db('stock_use')->insertGetId($stockUseData);
                    }
                }

                // 更新distributing表状态
                $distributingData = [
                    'status' => $overStatus ? 4 : 2,
                    'update_time' => time(),
                ];
                $change_ret=db('distributing')->where('id', $id)->update($distributingData);
                db()->commit();
                return $this->Json(1, '配料完成');
			}
		}

    	foreach ($omList as $k => &$v) {
    		// 需用量
			$v['totalNum'] = $v['material_dosage'] * $shicaiCount;

			// 库存现配量
			$stockNum = $stockService->getStockLeft($v['material_id'],$orderInfo['factory_id']);
			/*$gmInfo = $generalMaterialService->getInfoByMaterialSku($v['mInfo']['material_sku']);
			$stock = arrayGet($gmInfo, 'stock', 0);*/
			$v['stockNum'] = $stockNum+0;

			// 已使用量
			$v['useNum'] = $stockLogService->getUseNum($v['material_id'], $orderId);
			$v['jing_material_dosage'] = round($orderInfo['quantity'] * $v['material_dosage'], 2);
			$v['total_material_dosage'] = round(($orderInfo['quantity'] * $v['material_dosage'])+($orderInfo['quantity'] * $v['material_dosage'])*$v['loss']/100, 2);
			// 获取实际配量
			$v['allotNum'] = $stockUseService->getAllotNum($v['material_id'], $orderId);

            //判断物料是否已经被批量出库
            $isBatch = db('stock')->field('stock')->where('factory_id',$factoryId)->where('material_id',$v['material_id'])
                      ->where('stock','>',0)->find();
            $v['tag'] = empty($isBatch) ? '' : '已批量出库';
    	}

    	$assign['id'] = $id;
    	$assign['isPrint'] = $isPrint;
    	$assign['pic'] = (new SkuService())->getPicBySku($orderInfo['sku']);
    	$assign['shicaiCount'] = $shicaiCount;
    	$assign['osList'] = $osList;
    	$assign['oInfo'] = $orderInfo;
    	$assign['dInfo'] = $distributingInfo;
    	$assign['omList'] = $omList;
    	$assign['factory_name'] = arrayGet([0 => '未分厂'] + getFactoryKV(true), $orderInfo['factory_id'], '');
    	$assign['systemUserKV'] = getSystemUserKV(1);
    	$assign['distributingUserKV'] = getTagUserKV('tag_distributing_user');
    	$assign['receiverUserKV'] = getTagUserKV('tag_receiver_user');
    	return $this->assign($assign)->fetch();
    }

    //批量出库清单
    public function batchDetail(){
        $id       = $this->request->param('id/d', 0);
        $page       = $this->request->param('page/d', 1);
        $limit      = $this->request->param('limit/d', 20);
        $action = $this->request->param('action/s', '');
        $stock_m_type = config('mimo.stock_m_type');//0常规1备料2余料

       $stock_action = db('stock_action')->where("id", $id)->find();
       $materialService = new MaterialService();
       $factoryKV = getFactoryKV(true);
       $storehouseKV = getStorehouseKV();
       $storeshelfKV = getStoreshelfKV();
       $stock_id = $stock_action["stock_id"];
       if($stock_id > 0){ //出库管理过来的请求
           $stock_list = db('stock_action')->field('stock_id')->where("batch_number", $stock_action['batch_number'])->select();
           $stock_ids = array_column($stock_list,'stock_id');
           $where[] = ['st.id','in',$stock_ids];
           $where[] = ["sa.batch_number",'=',$stock_action['batch_number']];
       }else{
           $where[] = ['stock', '>', 0];//筛掉库存为0的数据
       }
        $where[] = ['sa.action_state', '=', 110];
       $order = 'material_id desc,update_time desc';
       $datalist = db('stock st')->where($where)
           ->join('stock_action sa', 'sa.stock_id=st.id', 'left')
           ->field("st.*,st.factory_id,sa.factory_id as select_factory_id,sa.id as action_id,sa.client_ordernum,sa.use_num")
           ->page($page)->limit($limit)->order($order)->select();
       foreach ($datalist as $k => &$v) {
           $v['stockall']=$v['stock']+$v['apply_used'];
           $v['caigou_number']= empty($v['caigou_number']) ? '' : "B".$v['caigou_number'];
           $v['minfo'] = $materialService->getInfoById($v['material_id']);
           $v['minfo']['mtype']=$materialService->formatMaterialType($v['minfo']['type']);
           $v['storehouse_name'] = arrayGet($storehouseKV, $v['storehouse_id'], '');
           $v['storeshelf_name'] = arrayGet($storeshelfKV, $v['storeshelf_id'], '');
       }
       $assign = [
           'showType'=>'finished',
           'action'=>$action,
           'stock_m_type'=>$stock_m_type,
           'storehouseKV'=>['' => '请选择']+$storehouseKV,
           'storeshelfKV'=>$storeshelfKV,
           'factoryKV' => ['' => '请选择',0=>'米莫总厂'] + $factoryKV,
           'isButton' =>2
       ];
       $assign['datalist']=$datalist;
       $template = $this->request->param('template', 'stock_new/detail_checkouts');
       return $this->assign($assign)->fetch($template);
    }
    //给预设置的通用料隐藏 不用分配 真实业务为通用料会批量先分配
    private function _setMaterialHide($omList){
        $findMaterialNames=db('material_tags')->where([["distribute_show",'=',0]])->column("name");
        foreach ($findMaterialNames as $key=>&$mname){
            $mname='/'.$mname.'/';
        }
        $replaceArr=array_keys($findMaterialNames);
        foreach ($omList as $key=>&$ominfo){
            if($ominfo['mInfo']['name']!=preg_replace($findMaterialNames,$replaceArr,$ominfo['mInfo']['name'])){
                unset($omList[$key]);
            }
        }
        return $omList;
    }

    /**
     * 确认收货
     *
     * @author KING
     * @date 2020年6月6日
     *
     */
    public function receipt() {
    	$id = $this->request->param('id/d', 0);

    	$info = db('distributing')->where("id", $id)->findOrEmpty();
    	if (!$info) {
    		return $this->Json(0, "配料清单不存在！");
    	}

    	$orderId = $info['order_id'];
    	$stockUseInfo = db('stock_use')->where("order_id", $orderId)->findOrEmpty();
    	if (empty($stockUseInfo)) {
    		return $this->Json(0, "实际配量信息未录入！");
    	}

    	$distributingData = [
    		'status' => 5,
    		'update_time' => time(),
    	];
    	db('distributing')->where('id', $id)->update($distributingData);

    	$this->addOrderLog($orderId, '', '配料确认收货');
    	return $this->Json(1, "确认收货成功！");
    }

    /**
     * 已配料列表
     *
     * @author KING
     * @date 2020年7月9日
     *
     * @return string
     */
    public function finished()
    {
    	if ($this->request->isAjax() || $this->request->param('export/d', 0)) {
    		$where      = $data = [];
    		$page       = $this->request->param('page/d', 1);
    		$limit      = $this->request->param('limit/d', 20);
    		$clientOrdernum    = $this->request->param('client_ordernum/s');
            $caigou_number = $this->request->param('caigou_number/s');
            $ct_type = $this->request->param('ct_type/d');
            $factory_id = $this->request->param('factory_id/d');
			$updateTime    = $this->request->param('update_time/s');
			$export     = $this->request->param('export/d', 0);
            $str = '';
            if ($clientOrdernum != '') {
                //$str .= " and (client_ordernum = {$clientOrdernum} or source_ordernum = {$clientOrdernum})";
            }
            switch (env('env_site')) {
                case 'riwei':
                    $ext_id = trim($this->request->param('ext_id'));
                    if ($ext_id != '') {
                        $temp = db('order')->field('id')->where([['ext_id', '=', $ext_id]])->find();
                        $str .= " and order_id = {$temp['id']}";
                    }
                    break;
            }
            if ($updateTime != '') {
                list($startTime, $endTime) = array_map('strtotime', explode('~', $updateTime));
                $endTime = $endTime+86399;
                $str .=" and st.update_time >= {$startTime} and st.update_time <= {$endTime} ";
            }
            if ($caigou_number != ''){
                $str .= " and st.caigou_number = {$caigou_number}";
            }
            if ($factory_id != ''){
                $str .= " and st.factory_id = {$factory_id}";
            }
            if ($export) {
                set_time_limit(0);
                ini_set('memory_limit', '1024M');
                $page = 1;
                $limit = 99999;
            }
            $offset = ($page -1) * $limit;
            //联合查询
            $order = 'update_time desc';
            $sql = "(select 1 as ct_type , id,factory_id,order_id,client_ordernum,caigou_number,update_time,'' as source_ordernum from ".config('database.prefix')."distributing st 
                   where status >= 4 {$str})"; //辅料出库
            $sql .="UNION ALL (select 2 as ct_type, st.id,st.factory_id,order_id,st.client_ordernum,st.caigou_number,st.update_time,stocktb.client_ordernum as source_ordernum from ".config('database.prefix')."stock_action st
                   left join ".config('database.prefix')."stock stocktb on st.stock_id=stocktb.id
                   where check_out_type = 1 and type = 2 and  action_state >= 110 {$str} group by batch_number) ";  //调拨出库
            $sql .="UNION ALL (select 3 as ct_type, st.id,st.factory_id,order_id,st.client_ordernum,st.caigou_number,st.update_time,stocktb.client_ordernum as source_ordernum from ".config('database.prefix')."stock_action st
                   left join ".config('database.prefix')."stock stocktb on st.stock_id=stocktb.id
                   where check_out_type =2 and type = 2 and action_state >= 110 {$str} group by batch_number) "; //占用出库
            $str1 = ' where 1=1';
            if($ct_type != ''){
                $str1 .= " and ct_type = {$ct_type}";
            }
            if ($clientOrdernum != '') {
                $str1 .= " and (client_ordernum = {$clientOrdernum} or source_ordernum = {$clientOrdernum})";
            }

            $res = db()->query("SELECT COUNT(id) as num FROM ({$sql}) tb {$str1}");
            $count = $res?$res[0]['num']:0;
            $list = db()->query("SELECT ct_type,id,factory_id,order_id,client_ordernum,caigou_number,update_time,source_ordernum FROM ({$sql}) tb {$str1} ORDER BY {$order} LIMIT {$offset},{$limit}");
            $factoryKV = getFactoryKV(true);
            foreach($list as $_dKey=>&$_dValue){
                $list[$_dKey]['factory_name'] = arrayGet($factoryKV,$_dValue['factory_id'],'');
                $_dValue['caigou_number']=$_dValue['caigou_number']!='' ? "B".$_dValue['caigou_number'] :$_dValue['caigou_number'];
                switch ($_dValue['ct_type']) {
                    case 1:
                        $_dValue['action_text'] = '辅料出库';
                        break;
                    case 2:
                        $_dValue['action_text'] = '调拨出库';
                        break;
                    case 3:
                        $_dValue['action_text'] = '占用出库';
                    default:
                }
            }
    		$data['data'] = $list;
    		$materialService = new MaterialService();
			//导出
            if ($export) {
				$orderMaterialService = new OrderMaterialService();
				$orderSizeService = new OrderSizeService();
				$orderService = new OrderService();
				$stockService = new StockService();
				$generalMaterialService = new GeneralMaterialService();
				$stockLogService = new StockLogService();
				$stockUseService = new StockUseService();
				foreach ($data['data'] as $kst => $vst) {
					$omList = $orderMaterialService->getListByOrderId($vst['order_id'], 'accessories');
					$shicaiCount = $orderSizeService->getShicaiCount($vst['order_id']);
					$orderInfo=$orderService->getInfoById($vst['order_id']);
					foreach ($omList as $k => &$v) {
						// 需用量
						$v['totalNum'] = $v['material_dosage'] * $shicaiCount;

						// 库存现配量
						$stockNum = $stockService->getStockLeft($v['material_id']);
						$gmInfo = $generalMaterialService->getInfoByMaterialSku($v['mInfo']['material_sku']);
						$stock = arrayGet($gmInfo, 'stock', 0);
						$v['stockNum'] = $stockNum+$stock;

						// 已使用量
						$v['useNum'] = $stockLogService->getUseNum($v['material_id'], $vst['order_id']);
						$v['jing_material_dosage'] = round($orderInfo['quantity'] * $v['material_dosage'], 2);
						$v['total_material_dosage'] = round(($orderInfo['quantity'] * $v['material_dosage'])+($orderInfo['quantity'] * $v['material_dosage'])*$v['loss']/100, 2);
						// 获取实际配量
						$v['allotNum'] = $stockUseService->getAllotNum($v['material_id'], $vst['order_id']);
					}
					$data['data'][$kst]['omList']=$omList;
				}
				//dump($data);exit();
                $this->_exportXls('已配料表-' .date('YmdHis'), $data['data']);
            }
    		$data['count'] = $count;
    		$data['code'] = 0;
    		$data['msg'] = '';
    		return json($data);
    	}

    	$assign = [
            'factoryKV' => ['' => '请选择'] + getFactoryKV(true),
            'ct_type' =>['' => '请选择','1'=>'辅料出库','2'=>'调拨出库','3'=>'占用出库'],
        ];
    	return $this->assign($assign)->fetch();
    }

	/**
	 * 已配料表导出
	 *
	 * @author 飞燕
	 * @date 2021年05月18日
	 *
	 */
	private function _exportXls($title,$data) {

		$head = ['编号','客户订单号','完成时间','物料名称','物料sku','单用量/件','需用量','总用量','净用量','库存现配量','已使用料','实际配量'];

    	$phpExcel = getExcelObj();
    	$sheet = $phpExcel->setActiveSheetIndex(0);
		$objDate = new \PHPExcel_Shared_Date();
		$objFormat = new \PHPExcel_Style_NumberFormat();
    	// 表头处理
    	foreach ($head as $k => $v) {
    		$cellKey = getExcelLetter($k);
    		$sheet->getColumnDimension($cellKey)->setWidth(20);
    		$sheet->setCellValue($cellKey . "1", $v);
    		$sheet->getRowDimension(1)->setRowHeight(30);
    		$sheet->getStyle($cellKey . "1")->getFont()->setBold(true);
    		$sheet->getStyle($cellKey . "1")->getAlignment()->setVertical('center');
    		$sheet->getStyle($cellKey . "1")->getFont()->getColor()->setARGB("FF0000FF");
    	}

    	$skuService = new SkuService();
    	require_once env('root_path').'plugins/excel/phpexcel/Classes/PHPExcel/Worksheet/Drawing.php';

    	$row = 2; // 当前行
    	$n = 0;
    	foreach ($data as $k => $v) {
    		if (count($v['omList']) > 1) {
    			$endCol = $row + count($v['omList']) - 1;
    			$sheet->mergeCells('A' . $row . ':A' . $endCol);
    			$sheet->mergeCells('B' . $row . ':B' . $endCol);
    			$sheet->mergeCells('C' . $row . ':C' . $endCol);
//    			$sheet->mergeCells('D' . $row . ':D' . $endCol);
//    			$sheet->mergeCells('E' . $row . ':E' . $endCol);
    		}

    		$sheet->getStyle('A' . $row)->getAlignment()->setVertical('center');
    		$sheet->getStyle('B' . $row)->getAlignment()->setVertical('center');
    		$sheet->getStyle('C' . $row)->getAlignment()->setVertical('center');
//    		$sheet->getStyle('D' . $row)->getAlignment()->setVertical('center');
//    		$sheet->getStyle('E' . $row)->getAlignment()->setVertical('center');

			$sheet->setCellValueExplicit('A' . $row, $v['id'], 's');
    		$sheet->setCellValueExplicit('B' . $row, $v['client_ordernum'], 'n');
			$sheet->setCellValueExplicit('C' . $row, $v['update_time']!=0?date('Y-m-d H:i:s', $v['update_time']):'', 's');
    		foreach ($v['omList'] as $sk => $sv) {
    			$sheet->setCellValueExplicit('D' . $row, arrayGet($sv['mInfo'], 'name', ''), 's');
    			$sheet->setCellValueExplicit('E' . $row, arrayGet($sv['mInfo'], 'material_sku', ''), 's');
    			// 单件用量
    			$sheet->setCellValueExplicit('F' . $row, $sv['material_dosage'], 'n');

    			// 需用量
    			$sheet->setCellValueExplicit('G' . $row,$sv['totalNum'], 'n');

				// 总用量
    			$sheet->setCellValueExplicit('H' . $row,$sv['total_material_dosage'], 'n');

    			// 净用量
    			$sheet->setCellValueExplicit('I' . $row, $sv['jing_material_dosage'], 's');

    			// 库存配置
    			$sheet->setCellValueExplicit('J' . $row, $sv['stockNum'], 'n');

    			// 已使用量
    			$sheet->setCellValueExplicit('K' . $row, $sv['useNum'], 'n');

    			// 实际配量
    			$sheet->setCellValueExplicit('L' . $row, $sv['allotNum'], 'n');
    			$row++;
    		}
    		$n++;
    	}

    	// Rename worksheet
    	$sheet->setTitle('worksheet');

    	header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    	header('Content-Disposition: attachment;filename="'.$title.'.xlsx"');
    	header('Cache-Control: max-age=0');
    	header('Cache-Control: max-age=1');
    	header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
    	header ('Cache-Control: cache, must-revalidate');
    	header ('Pragma: public');

    	$objWriter = \PHPExcel_IOFactory::createWriter($phpExcel, 'Excel2007');
    	$objWriter->save('php://output');
    	exit();
	}

	/**
	 * 修改客户单件用量
	 *
	 * @author King
	 * @date 2021年9月2日
	 *
	 */
	public function customerDosageEdit(){
		$customerDosage     = $this->request->param('customer_dosage/f', 0);
		$mid       = $this->request->param('mid/d', 0);
    	$orderId       = $this->request->param('order_id/d', 0);
    	$upData = [
    		'customer_dosage' => $customerDosage,
    		'update_time' => time(),
    	];
    	if ($mid) {
    		$orderMaterialService = new OrderMaterialService();
    		$omInfo = $orderMaterialService->getInfoById($mid);
    		$ret = db('order_material')->where('mid', $mid)->update($upData);
    		$this->addOrderLog($orderId, '', "保存物料[{$omInfo['mInfo']['name']}]客户单件用量");
    	}

    	if ($ret) {
    		return $this->Json(1, '保存客户单件用量成功');
    	} else return $this->Json(0);
	}
}